<template>
  <img
    :src="currentSrc"
    :alt="alt"
    :class="avatarClass"
    @error="handleError"
    @load="handleLoad"
  />
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { APP_CONSTANTS } from '@/utils/constants'

interface Props {
  src?: string
  alt?: string
  size?: 'small' | 'medium' | 'large'
  shape?: 'circle' | 'square'
  fallback?: string
}

const props = withDefaults(defineProps<Props>(), {
  src: '',
  alt: '头像',
  size: 'medium',
  shape: 'circle',
  fallback: APP_CONSTANTS.DEFAULT_AVATAR
})

const currentSrc = ref(props.src || props.fallback)
const hasError = ref(false)
const isLoading = ref(true)

// 计算头像样式类
const avatarClass = computed(() => [
  'avatar-image',
  `avatar-image--${props.size}`,
  `avatar-image--${props.shape}`,
  {
    'avatar-image--loading': isLoading.value,
    'avatar-image--error': hasError.value
  }
])

// 处理图片加载错误
const handleError = () => {
  if (!hasError.value && currentSrc.value !== props.fallback) {
    hasError.value = true
    currentSrc.value = props.fallback
    isLoading.value = false
  }
}

// 处理图片加载成功
const handleLoad = () => {
  isLoading.value = false
  hasError.value = false
}

// 监听 src 变化，重置状态
watch(() => props.src, (newSrc) => {
  if (newSrc && newSrc !== currentSrc.value) {
    hasError.value = false
    isLoading.value = true
    currentSrc.value = newSrc
  }
}, { immediate: true })
</script>

<style scoped>
.avatar-image {
  display: block;
  object-fit: cover;
  transition: opacity 0.3s ease;
}

.avatar-image--small {
  width: 24px;
  height: 24px;
}

.avatar-image--medium {
  width: 40px;
  height: 40px;
}

.avatar-image--large {
  width: 60px;
  height: 60px;
}

.avatar-image--circle {
  border-radius: 50%;
}

.avatar-image--square {
  border-radius: 4px;
}

.avatar-image--loading {
  opacity: 0.7;
}

.avatar-image--error {
  opacity: 0.8;
}
</style>